/**
 * Copyright (c) 2023 murenchao
 * taomu is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *       http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package cool.taomu.utils

import java.io.BufferedOutputStream
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import java.nio.file.Files
import java.util.zip.GZIPOutputStream
import org.apache.commons.compress.archivers.tar.TarArchiveEntry
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream
import org.apache.commons.io.IOUtils
import java.io.FileInputStream
import java.io.BufferedInputStream
import java.io.OutputStream

class TarGzUtils {
	def zxvf(String srcPath, String destPath) {
		var file = new File(srcPath);
		try(var gcis = new GzipCompressorInputStream(Files.newInputStream(file.toPath()))) {
			try(var tais = new TarArchiveInputStream(gcis)) {
				var TarArchiveEntry entry;
				var targetDir = new File(destPath);
				while ((entry = tais.nextTarEntry) !== null) {
					if (!entry.isDirectory) {
						var targetFile = new File(targetDir, entry.name);
						var parent = targetFile.parentFile;
						if (!parent.exists) {
							parent.mkdirs
						}
						IOUtils.copy(tais, Files.newOutputStream(targetFile.toPath));
					}
				}
			}
		}
	}

	private def getGZIPOutputStream(OutputStream os) {
		return new GZIPOutputStream(os);
	}

	def zcvf(String srcPath, String destPath) {
		try(var fos  = new FileOutputStream(destPath)) {
			try(var bos = new BufferedOutputStream(fos)) {
				try(var gos = this.getGZIPOutputStream(bos) ) {
					try(var taos = new TarArchiveOutputStream(gos)) {
						taos.longFileMode = TarArchiveOutputStream.LONGFILE_POSIX;
						addFilesToTarGz(srcPath, "", taos);
					}
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace;
		}
	}

	private def void addFilesToTarGz(String srcPath, String parent, TarArchiveOutputStream taos) {
		var file = new File(srcPath);
		val name = parent + file.name;
		taos.putArchiveEntry(new TarArchiveEntry(file, name));
		if (file.isFile) {
			try(var fis = new FileInputStream(file)) {
				try(var bis = new BufferedInputStream(fis)) {
					IOUtils.copy(bis, taos);
					taos.closeArchiveEntry;
				}
			}
		} else if (file.isDirectory) {
			taos.closeArchiveEntry;
			file.listFiles.forEach [
				addFilesToTarGz(it.absolutePath, name + File.separator, taos);
			]
		}
	}

}
